import { useEffect, useMemo,createContext } from "react";
import { useVm, genReducer } from "./useVm";

// 模拟后台
let backData = [
  { id: 1, content: "hahahaha 上班去", done: false },
  { id: 2, content: "yoyoyoy  下班了", done: false },
  { id: 3, content: "done  done done 快开门", done: true },
];
const $api = {
  getTodo: () => Promise.resolve([...backData]),
  remove: (todo) => {
    backData=backData.filter((t) => t.id !== todo.id);
    return Promise.resolve(true);
  },
  add: (content) => {
    $api.guid = $api.guid || 4;
    backData.push({ id: $api.guid++, content, done: false });
    return Promise.resolve(true);
  },
  setDone: (todo) => {
    backData.filter((t) => t.id == todo.id).done = true;
    return Promise.resolve(true);
  },
};

// 1、初始state一定是聚合态对象
let state = {
  title: "Todo Demo",
  inputStr: "",
  todoList: [],
};

// 2、所有的动作函数，
let fn = {
  // 同步方法，名称任意，必须返回一个 { }聚合态的值，方便自动合并状态值
  updateInputStr: (preState,e) => {
    return { inputStr: e.target.value }
  },
  // 异步方法一、使用promise
  // 异步方法名必须以“Async" 或 "$" 结尾，以区分函数的行为。
  getTodoListAsync: (preState) => {
    return $api.getTodo().then((list) => {
      return {
        todoList: list,
      };
    });
  },
  // 异步方法2、使用async
  setDoneAsync: async (preState, todo) => {
    await $api.setDone(todo);
    preState.todoList.find((t) => t.id == todo.id).done = true;
    return {
      todoList: [...preState.todoList],
    };
  },
  addTodo$: async (preStsate) => {
    // 没有输入todo内容，则忽略添加。但此时一定要返回一个Promise值
    if (preStsate.inputStr == "") {
      return Promise.resolve({});
    }
    await $api.add(preStsate.inputStr);
    let list = await $api.getTodo();
    return {
      todoList: list,
      inputStr: "",
    };
  },
  removeTodo$: async (preStsate, todo) => {
    await $api.remove(todo);
    let list = await $api.getTodo();
    return {
      todoList: list,
    };
  },
};

//3、准备reducer
let reducer = genReducer(fn);
export const TodoCtx=createContext();

//4、 书写页面要使用的Hook, 这属于自定义Hook，必须用use打头。
export default function useTodo() {
  let { state: todoState, fn: todoFn } = useVm(state, fn, reducer);

  //#region  5、 扩展功能，其它生命周期钩子，第三方hook的编写在这里。
  //  扩展属性， 类比为computed属性！
  //  可以使用原始js
  todoState.doneList = todoState.todoList.filter((t) => t.done);
  //  也可以使用 useMemo  Hook
  todoState.unDoneList = useMemo(() => todoState.todoList.filter((t) => !t.done), [todoState.todoList]);

  //  也可以编写 useEffect 处理额外事件,相当于watch
  useEffect(() => {
    document.title = todoState.title + "  [" + todoState.todoList.length + "]";
  });
  useEffect(() => {
    todoFn.getTodoListAsync();
  }, []);
  //#endregion

  // 6、返回相应的对象，用于模板中绑定值和函数
  return { todoState, todoFn ,TodoCtx};
}
